<?php

declare(strict_types=1);
/**
 * This file is part of Hyperf.
 *
 * @link     https://www.hyperf.io
 * @document https://hyperf.wiki
 * @contact  group@hyperf.io
 * @license  https://github.com/hyperf/hyperf/blob/master/LICENSE
 */

namespace App\Logic;

use App\Model\FollowAnchor;
use App\Model\Live;
use App\Model\Play;
use App\Model\PlayCollect;
use App\Model\PlayDatum;
use App\Model\PlayPlayer;
use App\Model\Project;
use App\Utils\Enum;
use App\Utils\LiveApi;
use Exception;
use Hyperf\Cache\Annotation\CacheAhead;
use Hyperf\Context\ApplicationContext;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\NotFoundExceptionInterface;
use stdClass;

class MatchLogic
{

    #[CacheAhead(prefix: 'match_list', ttl: 120, aheadSeconds: 50, lockSeconds: 10)]
    public static function getMatchListCache($sportId, $status, $time = '', $offset = 0, $pageSize = 30): array
    {
        $query = Play::query()->where('sport_id', $sportId);
        if ($status) {
            $query->where('match_status', $status);
        } else {
            $query->where('match_status', '<', Enum\MatchEnum::MATCH_STATUS_END);
        }
        if (!empty($time)) {
            $query->whereBetween('match_time', [strtotime($time), strtotime($time . ' 23:59:59')]);
        }
        $total = $query->count();
        if ($total) {
            $data = $query->with(['live' => function ($query) {
                return $query->with(['user', 'anchor']);
            }])->when($pageSize, function ($query) use ($offset, $pageSize) {
                $query->limit($pageSize);
                if ($offset) {
                    $query->offset($offset);
                }
            })->orderBy('match_time')->get();
        }
        return [$total, isset($data) && $data ? $data->toArray() : []];
    }

    /**
     * 搜索比赛
     * @param $userid
     * @param $input
     * @return array
     */
    public static function searchMatchList($userid, $input): array
    {
        $query = Play::query()->where('sport_id', $input['query']['sportId'])->whereBetween('match_time', [time() - 1 * 86400, time() + 3 * 86400])->where('game_name', 'like', '%' . $input['query']['keyword'] . '%');
        $total = $query->count();
        if ($total) {
            $data = $query->with(['live' => function ($query) {
                return $query->with(['user', 'anchor']);
            }])->orderBy('match_time')->get();
        }
        return [$total, isset($data) && $data ? $data->toArray() : []];
    }

    /**
     * 获取比赛列表.
     */
    public static function getMatchList($userid, $input): array
    {
        [$pageNum, $pageSize, $offset] = parsePageParams($input);
        if (empty($input['query']['keyword'])) {
            [$total, $res] = self::getMatchListCache($input['query']['sportId'], $input['query']['status'] ?? 0, $input['query']['time'] ?? '', $offset, $pageSize);
        } else {
            [$total, $res] = self::searchMatchList($userid, $input);
        }
        if (!empty($res)) {
            $records = [];
            $matchIds = [];
            foreach ($res as $r) {
                $r['homeTeams'] = new_json_decode($r['home_double_teams']);
                $r['awayTeams'] = new_json_decode($r['away_double_teams']);
                if (!empty($r['homeTeams'])) {
                    array_walk($r['homeTeams'], function (&$v) {
                        $v['logo'] = img_url($v['logo']);
                    });
                }
                if (!empty($r['awayTeams'])) {
                    array_walk($r['awayTeams'], function (&$v) {
                        $v['logo'] = img_url($v['logo'], 32);
                    });
                }
                $match = [
                    'sportId' => $r['sport_id'],
                    'matchId' => $r['match_id'],
                    'statusId' => $r['match_status_id'],
                    'matchTime' => $r['match_time'],
                    'matchStatus' => $r['match_status'],
                    'spMatchStatus' => $r['sp_match_status'],
                    'homeTeam' => [
                        'doubleTeams' => $r['homeTeams'] ?: null,
                        'id' => $r['home_team_id'],
                        'name' => $r['home_team_name'],
                        'logo' => img_url($r['home_team_logo'], 32),
                    ],
                    'homeScores' => new_json_decode($r['home_team_scores']),
                    'awayScores' => new_json_decode($r['away_team_scores']),
                    'awayTeam' => [
                        'doubleTeams' => $r['awayTeams'] ?: null,
                        'id' => $r['away_team_id'],
                        'name' => $r['away_team_name'],
                        'logo' => img_url($r['away_team_logo'], 32),
                    ],
                    'gameId' => $r['game_id'],
                    'gameName' => $r['game_name'],
                    'gameLogo' => img_url($r['game_logo'], 32),
                    'times' => new_json_decode($r['times']),
                    'hasVideo' => $r['video_url'],
                    'hasAnimation' => !empty($r['animate_url']),
                    'isColl' => Enum\MatchEnum::COLLECT_NOT, // TODO 是否关注
                    'anchorList' => [],
                ];
                if ($r['sport_id'] == Enum\MatchEnum::SPORT_TENNIS) {
                    $match['serve'] = $r['tennis_serve'];
                }
                if ($r['sport_id'] == Enum\MatchEnum::SPORT_VOLLEYBALL) {
                    $match['vbScores'] = new_json_decode($r['vb_scores']);
                }
                if (!empty($r['live'])) {
                    foreach ($r['live'] as $live) {
                        $match['anchorList'][] = [
                            'roomId' => $live['room_id'],
                            'roomName' => $live['room_name'],
                            'roomCover' => $live['room_cover'],
                            'roomIntroduce' => $live['introduce'],
                            'userId' => $live['userid'],
                            'userName' => $live['user']['username'],
                            'nickName' => $live['user']['nickname'],
                            'userAvatar' => img_url($live['user']['avatar'], 32),
                            'fansCount' => $live['anchor']['fans_count'],
                            'visitHistory' => $live['visit_history'],
                            'liveStatus' => $live['status'],
                            'playStreamAddress' => $live['play_stream_address'],
                        ];
                    }
                }
                $records[] = $match;
                $matchIds[] = $r['match_id'];
            }
            if ($userid && !empty($matchIds)) {
                $rs = PlayCollect::query()->select(['match_id'])->where('userid', $userid)->whereIn('match_id', $matchIds)->get();
                if (!empty($rs)) {
                    foreach ($rs as $r) {
                        $idx = array_search($r['match_id'], $matchIds);
                        $records[$idx]['isColl'] = Enum\MatchEnum::COLLECT_OK;
                    }
                }
            }
            //赛事聚合
            $data = [];
            foreach ($records as $r) {
                if (isset($data[$r['gameId']])) {
                    $data[$r['gameId']]['matchDetailList'][] = $r;
                } else {
                    $data[$r['gameId']] = [
                        'gameId' => $r['gameId'],
                        'gameName' => $r['gameName'],
                        'gameLogo' => $r['gameLogo'],
                        'sportId' => $r['sportId'],
                        'matchDetailList' => [$r]
                    ];
                }
            }
            $records = array_values($data);
            unset($data);
        }

        return [
            'total' => $total,
            'pages' => ceil($total / $pageSize),
            'records' => $records ?? [],
        ];
    }

    /**
     * 获取预约比赛
     * @param $userid
     * @return array
     */
    public static function myAttentionMatchList($userid): array
    {
        $res = PlayCollect::whereHas('match', function ($q) {
            $q->whereIn('match_status', [Enum\MatchEnum::MATCH_STATUS_WAIT, Enum\MatchEnum::MATCH_STATUS_ING]);
        })->with(['match', 'live' => function ($q) {
            $q->with(['user', 'anchor']);
        }])->get()->toArray();
        if (!$res) {
            return [];
        }
        usort($res, function ($a, $b) {
            if ($a['match']['match_time'] == $b['match']['match_time']) {
                return 0;
            } else {
                return $a['match']['match_time'] > $b['match']['match_time'] ? 1 : -1;
            }
        });

        $records = [];
        foreach ($res as $r) {
            $gameId = $r['match']['game_id'];
            if (!isset($records[$gameId])) {
                $records[$gameId] = [
                    'gameId' => $r['match']['game_id'],
                    'gameName' => $r['match']['game_name'],
                    'gameLogo' => img_url($r['match']['game_logo'], 32),
                    'sportId' => $r['match']['sport_id'],
                    'matchDetailList' => []
                ];
            }

            $homeTeams = new_json_decode($r['match']['home_double_teams']);
            $awayTeams = new_json_decode($r['match']['away_double_teams']);
            if (!empty($homeTeams)) {
                array_walk($homeTeams, function (&$v) {
                    $v['logo'] = img_url($v['logo'], 32);
                });
            }
            if (!empty($awayTeams)) {
                array_walk($awayTeams, function (&$v) {
                    $v['logo'] = img_url($v['logo'], 32);
                });
            }
            $match = [
                'sportId' => $r['match']['sport_id'],
                'matchId' => $r['match']['match_id'],
                'statusId' => $r['match']['match_status_id'],
                'matchTime' => $r['match']['match_time'],
                'matchStatus' => $r['match']['match_status'],
                'homeTeam' => [
                    'doubleTeams' => $homeTeams ?: null,
                    'id' => $r['match']['home_team_id'],
                    'name' => $r['match']['home_team_name'],
                    'logo' => img_url($r['match']['home_team_logo'], 32),
                ],
                'homeScores' => new_json_decode($r['match']['home_team_scores']),
                'awayScores' => new_json_decode($r['match']['away_team_scores']),
                'awayTeam' => [
                    'doubleTeams' => $awayTeams ?: null,
                    'id' => $r['match']['away_team_id'],
                    'name' => $r['match']['away_team_name'],
                    'logo' => img_url($r['match']['away_team_logo'], 32),
                ],
                'gameId' => $r['match']['game_id'],
                'gameName' => $r['match']['game_name'],
                'gameLogo' => img_url($r['match']['game_logo'], 32),
                'times' => new_json_decode($r['match']['times']),
                'hasVideo' => $r['match']['video_url'],
                'hasAnimation' => !empty($r['match']['animate_url']),
                'isColl' => Enum\MatchEnum::COLLECT_OK,
                'anchorList' => [],
            ];
            if ($r['match']['sport_id'] == Enum\MatchEnum::SPORT_TENNIS) {
                $match['serve'] = $r['match']['tennis_serve'];
            }
            if ($r['match']['sport_id'] == Enum\MatchEnum::SPORT_VOLLEYBALL) {
                $match['vbScores'] = new_json_decode($r['match']['vb_scores']);
            }
            if (!empty($r['live'])) {
                foreach ($r['live'] as $live) {
                    $match['anchorList'][] = [
                        'roomId' => $live['room_id'],
                        'roomName' => $live['room_name'],
                        'roomCover' => $live['room_cover'],
                        'roomIntroduce' => $live['introduce'],
                        'userId' => $live['userid'],
                        'userName' => $live['user']['username'],
                        'nickName' => $live['user']['nickname'],
                        'userAvatar' => img_url($live['user']['avatar'], 32),
                        'fansCount' => $live['anchor']['fans_count'],
                        'visitHistory' => $live['visit_history'],
                        'liveStatus' => $live['status'],
                        'playStreamAddress' => $live['play_stream_address'],
                    ];
                }
            }
            $records[$gameId]['matchDetailList'][] = $match;
        }
        unset($res);
        return array_values($records);
    }

    #[CacheAhead(prefix: 'live_match', ttl: 60, aheadSeconds: 30, lockSeconds: 5)]
    private static function _getMatchLiveList(): array
    {
        $res = Live::where('match_id', '<>', '')->where('status', Enum\LiveEnum::STATUS_LIVING)->whereIn('match_status', [Enum\MatchEnum::MATCH_STATUS_ING, Enum\MatchEnum::MATCH_STATUS_WAIT])->with(['match', 'anchor', 'user'])->orderBy('match_status', 'desc')->orderBy('match_time')->get();
        $data = [];
        if (!$res->isEmpty()) {
            foreach ($res as $r) {
                if (!isset($data[$r['match_id']])) {
                    $data[$r['match_id']] = [
                        'isColl' => 0,
                        'gameId' => $r['match']['game_id'],
                        'gameName' => $r['match']['game_name'],
                        'gameLogo' => img_url($r['match']['game_logo'], 32),
                        'matchId' => $r['match_id'],
                        'sportId' => $r['match']['sport_id'],
                        'matchTime' => $r['match_time'],
                        'matchStatus' => $r['match_status'],
                        'result' => [
                            'sportId' => $r['match']['sport_id'],
                            'matchId' => $r['match']['match_id'],
                            'homeTeam' => [
                                'id' => $r['match']['home_team_id'],
                                'name' => $r['match']['home_team_name'],
                                'logo' => img_url($r['match']['home_team_logo'], 48),
                                'sportId' => $r['match']['sport_id'],
                            ],
                            'homeScores' => new_json_decode($r['match']['home_team_scores']),
                            'awayTeam' => [
                                'id' => $r['match']['away_team_id'],
                                'name' => $r['match']['away_team_name'],
                                'logo' => img_url($r['match']['away_team_logo'], 48),
                                'sportId' => $r['match']['sport_id'],
                            ],
                            'awayScores' => new_json_decode($r['match']['away_team_scores']),
                            'matchStatus' => $r['match']['match_status'],
                            'spMatchStatus' => $r['match']['sp_match_status'],
                            'matchTime' => $r['match_time'],
                            'statusId' => $r['match']['match_status_id'],
                            'times' => new_json_decode($r['match']['times']),
                            'videoUrl' => $r['match']['video_url'],
                            'animateUrl' => $r['match']['animate_url'],
                        ],
                        'watchNum' => 0,
                        'anchorAppointmentVoList' => []
                    ];
                }
                $data[$r['match_id']]['anchorAppointmentVoList'][] = [
                    'uid' => $r['anchor']['userid'],
                    'roomId' => $r['anchor']['room_id'],
                    'nickName' => $r['user']['nickname'],
                    'userName' => $r['user']['username'],
                    'visitHistory' => $r['visit_history'],
                    'userAvatar' => img_url($r['user']['avatar'], 64),
                    'liveStatus' => $r['live_status']
                ];
            }
        }
        return array_values($data);
    }

    /**
     * 直播中的比赛（含主播信息）
     * @param $userid
     * @return array
     */
    public static function getMatchLiveList($userid): array
    {
        $data = self::_getMatchLiveList();
        if ($userid && !empty($data)) {
            $matchIds = array_column($data, 'matchId');
            $keyMap = array_combine($matchIds, array_keys($data));
            $res = PlayCollect::query()->whereIn('match_id', $matchIds)->select(['match_id'])->get();
            if (!$res->isEmpty()) {
                foreach ($res as $r) {
                    $data[$keyMap[$r['match_id']]]['isColl'] = 1;
                }
            }
        }
        return $data;
    }

    /**
     * 获取比赛信息
     * @param $userid
     * @param $matchId
     * @param $roomId
     * @return array
     * @throws Exception
     */
    public static function getMatchInfo($userid, $matchId, $roomId): array
    {
        $match = Play::query()->where('match_id', $matchId)->first();
        if (!$match) {
            throw new Exception('比赛不存在');
        }
        $isColl = 0;
        if ($userid && PlayCollect::query()->where(['userid' => $userid, 'match_id' => $matchId])->exists()) {
            $isColl = 1;
        }
        $data = [
            'matchId' => $match['match_id'],
            'sportId' => $match['sport_id'],
            'animation' => [
                'url' => $match['animate_url'],
            ],
            'game' => [
                'id' => $match['game_id'],
                'name' => $match['game_name'],
                'logo' => img_url($match['game_logo'], 80),
            ],
            'match' => [
                'homeTeam' => [
                    'id' => $match['home_team_id'],
                    'name' => $match['home_team_name'],
                    'logo' => img_url($match['home_team_logo'], 80),
                ],
                'awayTeam' => [
                    'id' => $match['away_team_id'],
                    'name' => $match['away_team_name'],
                    'logo' => img_url($match['away_team_logo'], 80),
                ],
                'matchStatus' => $match['match_status'],
                'statusId' => (int)$match['match_status_id'],
                'matchTime' => $match['match_time'],
                'videoUrl' => $match['video_url'],
                'times' => new_json_decode($match['times']),
                'isColl' => $isColl,
            ],
            'tabList' => MatchLogic::getTabs($matchId, $roomId)
        ];
        if ($match['tennis_double_flag']) {
            $homeTeams = new_json_decode($match['home_double_teams']);
            if (!empty($homeTeams)) {
                array_walk($homeTeams, function (&$t) {
                    $t['logo'] = img_url($t['logo'], 80);
                });
                unset($data['match']['homeTeam']['logo']);
                $data['match']['homeTeams'] = $data['match']['homeTeam']['doubleTeams'] = $homeTeams;
            }
            $awayTeams = new_json_decode($match['away_double_teams']);
            if (!empty($awayTeams)) {
                array_walk($awayTeams, function (&$t) {
                    $t['logo'] = img_url($t['logo'], 80);
                });
                unset($data['match']['homeTeam']['logo']);
                $data['match']['awayTeams'] = $data['match']['awayTeam']['doubleTeams'] = $awayTeams;
            }
        }
        if ($match['sport_id'] == Enum\MatchEnum::SPORT_TENNIS) {
            $data['match']['tennisDoubleFlag'] = $match['tennis_double_flag'];
            $data['match']['points'] = new_json_decode($match['tennis_game_points']);
            $data['tennisScores'] = ['data' => new_json_decode($match['tennis_scores'])];

            $stats = PlayDatum::query()->where('match_id', $match['match_id'])->value('stats');
            $data['tennisSetStats'] = ['matchId' => $match['match_id'], 'sets' => new_json_decode($stats)];
        }
        if ($match['sport_id'] == Enum\MatchEnum::SPORT_VOLLEYBALL) {
            $data['match']['vbScores'] = new_json_decode($match['vb_scores']);
        } else {
            $data['match']['homeScores'] = new_json_decode($match['home_team_scores']);
            $data['match']['awayScores'] = new_json_decode($match['away_team_scores']);
        }
        return $data;
    }

    /**
     * 获取比赛直播主播.
     * @param mixed $matchId
     * @param mixed $userid
     */
    public static function getRelationAnchor($matchId, $userid = 0): array
    {
        $list = Live::query()->where('live.match_id', $matchId)->leftJoin('user', 'user.id', '=', 'live.userid')->leftJoin('user_model_anchor', 'user_model_anchor.userid', '=', 'live.userid')->get();
        $data = [];
        $userIds = [];
        foreach ($list as $r) {
            $data[] = [
                'userImage' => img_url($r['avatar']),
                'houseId' => $r['houseId'],
                'userName' => $r['username'],
                'visitHistory' => $r['visit_history'],
                'matchId' => $r['match_id'],
                'liveStatus' => $r['live_status'],
                'nickname' => $r['nickname'],
                'fansCount' => $r['fans_count'],
                'userId' => $r['user_id'],
                'followStatus' => Enum\UserEnum::UNFOLLOW,
            ];
            $userIds[] = $r['user_id'];
        }
        if (!empty($userIds) && $userid) {
            $follow = FollowAnchor::query()->where([['userid' => $userid], ['anchor_userid', 'in', $userIds]])->get();
            if ($follow) {
                foreach ($follow as $f) {
                    $idx = array_search($f['anchor_userid'], $userIds);
                    if ($idx) {
                        $data[$idx]['followStatus'] = Enum\UserEnum::FOLLOWED;
                    }
                }
            }
        }
        return $data;
    }

    /**
     * 获取比赛指数.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getOdds($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('odds')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['odds']);
    }

    /**
     * 获取比赛趋势
     * @throws Exception
     */
    public static function getTrend($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('trend')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['trend']);
    }

    /**
     * 获取重要事件
     * @throws Exception
     */
    public static function getIncidents($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('incidents')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['incidents']);
    }

    /**
     * 获取比赛各项状态.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getStats($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('stats')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['stats']);
    }

    /**
     * 获取阵容.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getLineup($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('lineup')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['lineup']);
    }

    /**
     * 获取球队统计.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getTeamStats($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('team_stats')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['team_stats']);
    }

    /**
     * 获取比赛分析.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getAnalysis($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('analysis')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['analysis']);
    }

    /**
     * 获取比赛TABLES.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getTables($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('tables')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['tables']);
    }

    /**
     * 获取比赛情报.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getNews($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('news')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['news']);
    }


    /**
     * 获取文字直播.
     * @param mixed $matchId
     * @throws Exception
     */
    public static function getTextLives($matchId)
    {
        $data = PlayDatum::query()->where('match_id', $matchId)->select('text_lives')->first();
        if (!$data) {
            throw new Exception('比赛不存在');
        }
        return new_json_decode($data['text_lives']);
    }

    /**
     * 获取可直播的比赛.
     * @param $input
     * @return array
     */
    public static function getLiveMatchList($input): array
    {
        $query = Play::query()->where('sport_id', $input['query']['sportId'])->where(function($query) {
           $query->where(['match_status' => Enum\MatchEnum::MATCH_STATUS_ING])->orWhere([['match_status', '=', Enum\MatchEnum::MATCH_STATUS_WAIT], ['match_time', '>', time()]]);
        });
        $total = $query->count();
        if ($total) {
            $res = $query->orderBy('match_time')->get()->toArray();
            $records = [];
            foreach ($res as $r) {
                $records[] = [
                    'matchId' => $r['match_id'],
                    'sportId' => $r['sport_id'],
                    'gameId' => $r['game_id'],
                    'gameName' => $r['game_name'],
                    'gameLogo' => img_url($r['game_logo'], 48),
                    'homeTeamId' => $r['home_team_id'],
                    'homeTeamName' => $r['home_team_name'],
                    'homeTeamLogo' => img_url($r['home_team_logo'], 48),
                    'awayTeamId' => $r['away_team_id'],
                    'awayTeamName' => $r['away_team_name'],
                    'awayTeamLogo' => img_url($r['away_team_logo'], 48),
                    'matchTime' => date('Y-m-d H:i', $r['match_time']),
                    'matchTimestamp' => $r['match_time'],
                ];
            }
        }
        return [
            'total' => $total,
            'pages' => 1,
            'records' => $records ?? []
        ];
    }

    /**
     * 获取比赛球员统计
     * @param $matchId
     * @param $playerId
     * @return array|false|mixed|stdClass
     * @throws Exception
     */
    public static function getMatchPlayerStats($matchId, $playerId): mixed
    {
        $stats = PlayPlayer::query()->where(['match_id' => $matchId, 'player_id' => $playerId])->first();
        if ($stats && !empty($stats['result'])) {
            return new_json_decode($stats['result']);
        }
        try {
            $api = ApplicationContext::getContainer()->get(LiveApi::class);
            $result = $api->getMatchPlayerStats($matchId, $playerId);
            if (!empty($result['data']['result'])) {
                if (empty($stats)) {
                    PlayPlayer::create([
                        'match_id' => $matchId,
                        'player_id' => $playerId,
                        'result' => new_json_encode($result['data']['result']),
                        'add_time' => time()
                    ]);
                } else {
                    PlayPlayer::query()->where('id', $stats['id'])->update(['result' => new_json_encode($result['data']['result'])]);
                }
                return $result['data']['result'];
            }
        } catch (NotFoundExceptionInterface|ContainerExceptionInterface $e) {
            //TODO
        }
        throw new Exception('获取失败');
    }

    /**
     * 获取比赛导航tab
     * @param $matchId
     * @param $roomId
     * @return string[]
     */
    public static function getTabs($matchId, $roomId): array
    {
        $fields = array_diff((new PlayDatum())->getFillable(), ['id', 'match_id']);
        $select = '';
        foreach ($fields as $field) {
            $select .= ",LENGTH(`{$field}`) AS `$field`";
        }

        $tabList = ['overview' => 1, 'chat' => 1, 'odds' => 'odds', 'anchor', 'redbill' => 'redbill', 'lineup' => 'lineup', 'team_stats' => 'statistics', 'analysis' => 'analysis', 'vote' => 'vote', 'news' => 'news', 'tables' => 'point'];
        $data = PlayDatum::query()->selectRaw(substr($select, 1))->where('match_id', $matchId)->first();
        $tabs = ['overview', 'chat', 'odds', 'anchor'];
        if ($roomId) {
            $tabs = ['chat', 'message', 'anchor', 'overview'];
        }
        if (Project::query()->where('match_id', $matchId)->exists()) {
            $tabs[] = 'redbill';
        }
        foreach ($data->toArray() as $field => $length) {
            if (intval($length) > 10 && isset($tabList[$field]) && !in_array($tabList[$field], $tabs)) {
                $tabs[] = $tabList[$field];
            }
        }
        return $tabs;
    }

    /**
     * 关注订阅比赛
     * @param $userid
     * @param $matchId
     * @return int
     * @throws Exception
     */
    public static function collectMatch($userid, $matchId): int
    {
        if (!Play::query()->where('match_id', $matchId)->exists()) {
            throw new  Exception('比赛不存在');
        }
        $collect = PlayCollect::query()->select(['id'])->where(['userid' => $userid, 'match_id' => $matchId])->first();
        if ($collect) {
            PlayCollect::query()->where('id', $collect['id'])->delete();
            return Enum\MatchEnum::COLLECT_NOT;
        } else {
            PlayCollect::create([
                'match_id' => $matchId,
                'userid' => $userid,
                'add_time' => time(),
                'notice_time' => 0,
            ]);
            return Enum\MatchEnum::COLLECT_OK;
        }
    }
}
